package com.ld.shieldsb.pdf;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * pdf转成图片<br>
 * pdfBox官网：https://pdfbox.apache.org/2.0/migration.html
 * 
 * @ClassName PDF2Img
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2018年1月10日 上午10:41:42
 *
 */
public class PDF2Img {
    /**
     * 
     * pdf转成一张图片
     * 
     * @Title pdf2multiImage
     * @author 吕凯
     * @date 2018年1月10日 上午10:42:56
     * @param pdf
     * @param outpath
     * @param endPage
     *            pdf的结束页码 【比如Pdf有3页，如果endPage=2，则将pdf中的前2页转成图片，如果超过pdf实际页数，则按实际页数转换】 void
     */
    public static void pdf2Image(PDDocument pdf, String outpath, int endPage) {
        try {
            PDFRenderer renderer = new PDFRenderer(pdf);
            List<BufferedImage> piclist = new ArrayList<BufferedImage>();
            int actSize = pdf.getNumberOfPages(); // pdf中实际的页数
            if (actSize < endPage) {
                endPage = actSize;
            }
            for (int i = 0; i < endPage; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 96, ImageType.RGB);
                piclist.add(image);
            }
            yPic(piclist, outpath);
            pdf.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将pdf中的maxPage页，转换成一张图片
     *
     * @param pdfFile
     *            pdf的路径
     * @param outpath
     *            输出的图片的路径[包括名称]
     * @param endPage
     *            pdf的结束页码 【比如Pdf有3页，如果endPage=2，则将pdf中的前2页转成图片，如果超过pdf实际页数，则按实际页数转换】
     */
    public static void pdf2Image(String pdfFile, String outpath, int endPage) {
        try {
            PDDocument pdf = PDDocument.load(new File(pdfFile));
            PDFRenderer renderer = new PDFRenderer(pdf);
            List<BufferedImage> piclist = new ArrayList<BufferedImage>();
            int actSize = pdf.getNumberOfPages(); // pdf中实际的页数
            if (actSize < endPage) {
                endPage = actSize;
            }
            for (int i = 0; i < endPage; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 96, ImageType.RGB);
                piclist.add(image);
            }
            yPic(piclist, outpath);
            pdf.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将宽度相同的图片，竖向追加在一起 ##注意：宽度必须相同
     *
     * @param piclist
     *            文件流数组
     * @param outPath
     *            输出路径
     */
    public static void yPic(List<BufferedImage> piclist, String outPath) {// 纵向处理图片
        if (piclist == null || piclist.size() <= 0) {
            System.out.println("图片数组为空!");
            return;
        }
        try {
            int height = 0; // 总高度
            int width = 0; // 总宽度
            int lheight = 0; // 临时的高度 , 或保存偏移高度
            int llheight = 0; // 临时的高度，主要保存每个高度
            int picNum = piclist.size(); // 图片的数量
            int[] heightArray = new int[picNum]; // 保存每个文件的高度
            BufferedImage buffer = null; // 保存图片流
            List<int[]> imgRGB = new ArrayList<int[]>(); // 保存所有的图片的RGB
            int[] limgRGB; // 保存一张图片中的RGB数据
            for (int i = 0; i < picNum; i++) {
                buffer = piclist.get(i);
                heightArray[i] = lheight = buffer.getHeight(); // 图片高度
                if (i == 0) {
                    width = buffer.getWidth(); // 图片宽度
                }
                height += lheight; // 获取总高度
                limgRGB = new int[width * lheight]; // 从图片中读取RGB
                limgRGB = buffer.getRGB(0, 0, width, lheight, limgRGB, 0, width);
                imgRGB.add(limgRGB);
            }
            lheight = 0; // 设置偏移高度为0
            // 生成新图片
            BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int i = 0; i < picNum; i++) {
                llheight = heightArray[i];
                if (i != 0) {
                    lheight += llheight; // 计算偏移高度
                }
                imageResult.setRGB(0, lheight, width, llheight, imgRGB.get(i), 0, width); // 写入流中
            }
            File outFile = new File(outPath);
            ImageIO.write(imageResult, "jpg", outFile); // 写图片
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void pdf2ImagePdf(String pdfFile, String outpath, int endPage) {
        try {
            Document docOut = new Document();
            docOut.setMargins(0, 0, 0, 0);
            FileOutputStream os = new FileOutputStream(outpath);
            PdfWriter.getInstance(docOut, os);
            docOut.open();
            PDDocument pdf = PDDocument.load(new File(pdfFile));
            PDFRenderer renderer = new PDFRenderer(pdf);
            int actSize = pdf.getNumberOfPages(); // pdf中实际的页数
            if (actSize < endPage) {
                endPage = actSize;
            }
            for (int i = 0; i < endPage; i++) {
                ByteArrayOutputStream bb = new ByteArrayOutputStream();
                BufferedImage image = renderer.renderImage(i, 1.25f);
                ImageIO.write(image, "jpg", bb);
                Image jpg = Image.getInstance(bb.toByteArray());
                jpg.scalePercent(80.0f); // 此处百分比与前面的分辨率参数相乘结果为1，则可保证等比输出。
                jpg.setAlignment(Image.ALIGN_CENTER);
                docOut.add(jpg);
            }
            pdf.close();
            docOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        String filePath = "C:/Users/Administrator/Desktop/A312kk1信用报告2017-12-14.pdf";
        String imgPath = "C:/Users/Administrator/Desktop/test.jpg";
        String imgPdfPath = "C:/Users/Administrator/Desktop/test.pdf";

//        pdf2multiImage(filePath, imgPath, 100);
        System.out.println("end1");
        pdf2Image(filePath, imgPdfPath, 100);
        System.out.println("end2");
    }
}
